#include "io_mng.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "encoder_logger.h"

static uint8_t is_first_output = 0;
int read_data_to_input_ctx(input_img_ctx_t *ctx, pix_fmt_e pix_fmt)
{
    FILE *file = fopen(ctx->filename, "rb");
    if (file == NULL) {
        ERR_LOG("open file error %s", ctx->filename);
        return -1;
    }
    fseek(file, 0, SEEK_END);
    ctx->data_len = ftell(file);
    fseek(file, 0, SEEK_SET);
    ctx->data = (uint8_t *)calloc(ctx->data_len, 1);
    uint64_t read_size = fread(ctx->data, 1, ctx->data_len, file);
    if (read_size != ctx->data_len) {
        ERR_LOG("read file error %s ret %lu read length %d", 
                ctx->filename, read_size, ctx->data_len);
        fclose(file);
        return -1;
    }

    fclose(file);
    INFO_LOG("read file %s length %d success", ctx->filename, ctx->data_len);
    if (pix_fmt == PIX_FMT_YUV420P) {
        if (ctx->data_len < (ctx->height * ctx->width * 3 / 2)) {
            ERR_LOG("read data len not enough %d expect %d\n", ctx->data_len, 
                (ctx->height * ctx->width * 3 / 2));
            return -1;
        }

        ctx->plane.y_data = ctx->data;
        ctx->plane.u_data = ctx->data + (ctx->width * ctx->height);
        ctx->plane.v_data = ctx->data + (ctx->width * ctx->height) + (ctx->width * ctx->height / 4);
    } else {
        ERR_LOG("Not support pix fmt %d\n", pix_fmt);
        return -1;
    }
    
    return 0;
}


int io_mng_write_nal_pack(nal_t *nal, const char *filename)
{
    if (nal == NULL || filename == NULL) {
        ERR_LOG("input args is null\n");
        return -1;
    }
    FILE *fp = NULL;
    if (is_first_output == 0) {
        is_first_output = 1;
        fp = fopen(filename, "wb");   // 清空写

    } else {
        fp = fopen(filename, "ab");   // 追加写
    }
    if(fp == NULL) {
        ERR_LOG("open file %s error\n", filename);
        return -1;
    }

    static const uint8_t start_code[] = {0x00, 0x00, 0x01};
    static const uint8_t long_start_code[] = {0x00, 0x00, 0x00, 0x01};

    if (nal->b_long_startcode == 1) {
        fwrite(long_start_code, 1, sizeof(long_start_code), fp);
    } else {
        fwrite(start_code, 1, sizeof(start_code), fp);
    }
    
    uint8_t nal_head = (nal->i_ref_idc << 5) | (nal->i_type & 0x1F);

    // 写入头
    fwrite(&nal_head, 1, sizeof(nal_head), fp);

    // 写入负载数据
    fwrite(nal->p_payload, 1, nal->i_payload, fp);
    fclose(fp);
}

